/*
Plugin to implement the MUC extension. http://xmpp.org/extensions/xep-0045.html
*/
/* jslint configuration: */
/* global document, window, setTimeout, clearTimeout, console,
    XMLHttpRequest, ActiveXObject,
    Base64, MD5,
    Strophe, $build, $msg, $iq, $pres 
*/

(function(Strophe) {
    Strophe.addConnectionPlugin('muc', {
        _connection: null,
        // The plugin must have the init function
        /***Function
        Initialize the MUC plugin. Sets the correct connection object and
        extends the namesace.
        */
        init: function(conn) {
            this._connection = conn;
            /* extend name space 
             *  NS.MUC - XMPP Multi-user chat namespace
             *              from XEP 45.  
             *
             */
            Strophe.addNamespace('MUC_OWNER', Strophe.NS.MUC + "#owner");
            Strophe.addNamespace('MUC_ADMIN', Strophe.NS.MUC + "#admin");
        },
        /***Function
        Join a multi-user chat room
        Parameters:
        (String) room - The multi-user chat room to join.
        (String) nick - The nickname to use in the chat room. Optional
        (Function) msg_handler_cb - The function call to handle messages from the
        specified chat room.
        (Function) pres_handler_cb - The function call back to handle presence
        in the chat room.
        (String) password - The optional password to use. (password protected
        rooms only)
        */
        join: function(room, nick, msg_handler_cb, pres_handler_cb, password) {
            var room_nick = this.test_append_nick(room, nick);
            var msg = StropheLib.$pres({
                    from: this._connection.jid,
                    to: room_nick
                })
                .c("x", { xmlns: Strophe.NS.MUC });
            if (password) {
                var password_elem = Strophe.xmlElement("password", [],
                    password);
                msg.cnode(password_elem);
            }
            if (msg_handler_cb) {
                this._connection.addHandler(function(stanza) {
                        var from = stanza.getAttribute('from');
                        var roomname = from.split("/");
                        // filter on room name
                        if (roomname[0] == room) {
                            return msg_handler_cb(stanza);
                        } else {
                            return true;
                        }
                    },
                    null,
                    "message",
                    null,
                    null,
                    null);
            }
            if (pres_handler_cb) {
                this._connection.addHandler(function(stanza) {
                        var xquery = stanza.getElementsByTagName("x");
                        if (xquery.length > 0) {
                            //Handle only MUC user protocol
                            for (var i = 0; i < xquery.length; i++) {
                                var xmlns = xquery[i].getAttribute("xmlns");

                                if (xmlns && xmlns.match(Strophe.NS.MUC)) {
                                    return pres_handler_cb(stanza);
                                }
                            }
                        }
                        return true;
                    },
                    null,
                    "presence",
                    null,
                    null,
                    null);
            }
            this._connection.send(msg);
        },
        /***Function
        Leave a multi-user chat room
        Parameters:
        (String) room - The multi-user chat room to leave.
        (String) nick - The nick name used in the room.
        (Function) handler_cb - Optional function to handle the successful leave.
        Returns:
        iqid - The unique id for the room leave.
        */
        leave: function(room, nick, handler_cb) {
            var room_nick = this.test_append_nick(room, nick);
            var presenceid = this._connection.getUniqueId();
            var presence = StropheLib.$pres({
                type: "unavailable",
                id: presenceid,
                from: this._connection.jid,
                to: room_nick
            });
            this._connection.addHandler(handler_cb,
                null,
                "presence",
                null,
                presenceid,
                null);
            this._connection.send(presence);
            return presenceid;
        },
        /***Function
        Parameters:
        (String) room - The multi-user chat room name.
        (String) nick - The nick name used in the chat room.
        (String) message - The message to send to the room.
        (String) type - "groupchat" for group chat messages or "chat" for private chat messages
        Returns:
        msgiq - the unique id used to send the message
        */
        message: function(room, nick, message, type) {
            var room_nick = this.test_append_nick(room, nick);
            type = type || "groupchat";
            var msgid = this._connection.getUniqueId();
            var msg = StropheLib.$msg({
                to: room_nick,
                from: this._connection.jid,
                type: type,
                id: msgid
            }).c("body", { xmlns: Strophe.NS.CLIENT }).t(message);
            msg.up().c("x", { xmlns: "jabber:x:event" }).c("composing");
            this._connection.send(msg);
            return msgid;
        },
        test_append_nick: function(room, nick) {
            var room_nick = room;
            if (nick) {
                room_nick += "/" + Strophe.escapeNode(nick);
            }
            return room_nick;
        }
    });
    /* jshint ignore:end */
})(StropheLib.Strophe);
